/*
 * This file is part of ELCube.
 *
 * ELCube is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * ELCube is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with ELCube.  If not, see <https://www.gnu.org/licenses/>.
 */
package cn.nkpro.elcube.co.spel;

import cn.nkpro.elcube.exception.NkException;
import cn.nkpro.elcube.utils.DateTimeUtilz;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * date:2021/12/22
 * description: 1、可以获取当前日期返回秒
 * @author :zxc
 */
@Component("SpELdate")
@SuppressWarnings("unused")
public class NkDateSpEL implements NkSpELInjection {

    //天
    private static final Long DAY = 1L;
    //周
    private static final Long WEEK = 7L;
    //月
    private static final Long MONTH = 30L;
    //季度
    private static final Long QUARTER= 90L;
    //半年
    private static final Long HALFYEAR = 180L;
    //年
    private static final Long YEAR = 365L;
    //每一天的秒数
    private static final Long SECOND = 86400L;

    //初始化还款单位
    private static final List<String> timeUnits = new ArrayList<>(Arrays.asList("DAY","WEEK","MONTH","QUARTER","HALFYEAR","YEAR"));

    /**
     * description：获取当前日期返回秒
     * @return 时间秒
     */
    public Long now(){
        // todo 这里应该返回当前时间的，但是却返回了当前0点，需要找个时间调整
        return DateTimeUtilz.todaySeconds();
    }
    /**
     * description：获取当前日期返回秒
     * @return 时间秒
     */
    public Long today(){
        return DateTimeUtilz.todaySeconds();
    }
    /**
     * description：格式化日期
     * @return 时间秒
     */
    public String format(Long seconds, String format){
        return DateTimeUtilz.format(seconds, format);
    }
    /**
     */
    public Integer get(int field){
        return Calendar.getInstance().get(field);
    }/**
     */
    public Integer get(int field,long date){
        Calendar instance = Calendar.getInstance();
        instance.setTimeInMillis(date * 1000);
        return instance.get(field);
    }

    /**
     * 计算两个日期相差的天数
     * @param date1 date1
     * @param date2 date2
     * @return 相差的天数
     */
    public Long diff(Long date1, Long date2){
        date1 = date1 == null ? 0 : date1;
        date2 = date2 == null ? 0 : date2;
        return (date1 - date2) / 86400;
    }

    public Long dateAdd(long date1, int day){
        return DateTimeUtilz.dateAdd(date1, day);
    }

    public Long monthAdd(long date1, int month){
        return DateTimeUtilz.monthAdd(date1, month);
    }

    public Long yearAdd(long date1, int year){
        return DateTimeUtilz.yearAdd(date1, year);
    }

    private static Pattern pattern = Pattern.compile("[^\\d]*((\\d{2,4})[年\\-])((\\d{1,2})[月\\-])((\\d{1,2})[日\\-]?)?[^\\d]*((\\d{1,2})[:时点]((\\d{1,2})[:分]((\\d{1,2})秒?)?)?)?.*");
    @SuppressWarnings("all")
    public Long parse(String str){
        //2022年4月12日
        //2022年4月12日 13:00:12
        //2022-4-12
        //2022-4-12 13:00:12
        if(StringUtils.isBlank(str)){
            return null;
        }
        Matcher matcher = pattern.matcher(str);
        if(matcher.matches()){
            int year = Integer.parseInt(matcher.group(2));
            if(year<=40){
                year = 2000+year;
            }else if(year < 99){
                year = 1900+year;
            }
            int month = Integer.parseInt(matcher.group(4));
            if(month<=12&&month>=1){

                Calendar calendar = Calendar.getInstance();
                calendar.set(year,month-1,Integer.parseInt(matcher.group(6)));

                String hour = matcher.group(8);
                String minute = matcher.group(10);
                String second = matcher.group(12);
                if(StringUtils.isNotBlank(hour)){
                    calendar.set(Calendar.HOUR_OF_DAY,Integer.parseInt(hour));
                }else{
                    calendar.set(Calendar.HOUR_OF_DAY,0);
                }
                if(StringUtils.isNotBlank(minute)){
                    calendar.set(Calendar.MINUTE,Integer.parseInt(minute));
                }else{
                    calendar.set(Calendar.MINUTE,0);
                }
                if(StringUtils.isNotBlank(second)){
                    calendar.set(Calendar.SECOND,Integer.parseInt(second));
                }else{
                    calendar.set(Calendar.SECOND,0);
                }
                calendar.set(Calendar.MILLISECOND,0);

                System.out.println(calendar.toInstant().toString());

                return calendar.getTimeInMillis()/1000;
            }
        }
        return null;
    }

    /**
     * @author 吴俊
     * Email wujun@newcore.net.cn
     * 创建日期: 2022-01-12
     * used to: 时间相加
     */
    @Deprecated
    public Long add(Long ... dates) throws NkException {
        if(dates.length < 2) throw new NkException("必须有两个参数及以上,请检查");
        return Arrays.stream(dates).mapToLong(date -> date).sum();
    }


    /**
     * @author 吴俊
     * Email wujun@newcore.net.cn
     * 创建日期: 2022-01-12
     * used to: 时间相减
     */
    @Deprecated
    public Long sub(Long ... dates) throws NkException {
        Long result;
        if(dates.length < 2) throw new NkException("必须有两个参数,请检查");
        result = dates[0] - dates[1];
        return result;
    }


    /**
     * @author 吴俊
     * Email wujun@newcore.net.cn
     * 创建日期: 2022-01-12
     * used to: 单位(天、周、月、季、半年、年) * 还款期限
     */
    @Deprecated
    public Long mul(String timeUnit,Object time) throws NkException {
        if(timeUnit == null || time == null || StringUtils.isBlank(timeUnit)) throw new NkException("两个参数都不能为空或空字符串，请检查");
        if(!timeUnits.contains(timeUnit)) throw new NkException("第一个参数请填写为--DAY,WEEK,MONTH,QUARTER,HALFYEAR,YEAR其中一个");
        Long result = null;
        switch (timeUnit){
            case "DAY":
                result = calculateTimeUnit(DAY,time);
                break;
            case "WEEK":
                result = calculateTimeUnit(WEEK,time);
                break;
            case "MONTH":
                result = calculateTimeUnit(MONTH,time);
                break;
            case "QUARTER":
                result = calculateTimeUnit(QUARTER,time);
                break;
            case "HALFYEAR":
                result = calculateTimeUnit(HALFYEAR,time);
                break;
            case "YEAR":
                result = calculateTimeUnit(YEAR,time);
                break;
        }
        return result;
    }

    private static Long calculateTimeUnit(Long timeUnit, Object time) throws NkException {
        Long result = null;
        int flag = 0;
        if(time instanceof Integer){
            result = timeUnit * SECOND * (Integer)time;
            flag++;
        }
        if(time instanceof Long){
            result = timeUnit * SECOND * (Long)time;
            flag++;
        }
        if(time instanceof Double){
            result = timeUnit * SECOND * ((Double) time).longValue();
            flag++;
        }
        if(flag == 0){
            throw new NkException("请检查数据类型,第二个参数类型只能为integer或者long或者double");
        }
        return result;
    }

}
